package com.hxd.mall.network.module

import android.util.Log
import com.hxd.mall.BuildConfig
import com.hxd.mall.constant.HxdConstants.Channel_Number
import com.hxd.mall.constant.HxdConstantsAccount.token
import com.hxd.mall.constant.HxdGlobalInfo
import com.hxd.mall.utils.open.DeviceInfoUtil
import com.hxd.mall.utils.open.HexinX509TrustManager
import com.hxd.mall.utils.open.MobileInfoManager
import dagger.Module
import dagger.Provides
import okhttp3.*
import java.io.File
import java.security.KeyManagementException
import java.security.NoSuchAlgorithmException
import java.security.SecureRandom
import java.util.concurrent.TimeUnit
import javax.inject.Named
import javax.inject.Singleton
import javax.net.ssl.SSLContext
import javax.net.ssl.SSLSocketFactory
import javax.net.ssl.TrustManager

/**
 * 提供多种okHttpClient构建方式
 * Created by qishuai on 2018/7/30.
 */
/**
 * 此类未使用，使用的是okHttpManager
 */
@Module
class OkHttpModule {

    @Singleton
    @Provides
    @Named("default")
    fun providerOkHttpClient(): OkHttpClient {
        // 指定缓存路径,缓存大小100Mb
        val cache =
            Cache(File(HxdGlobalInfo.instance.cacheDir, "HttpCache"), (1024 * 1024 * 100).toLong())
        val builder = OkHttpClient.Builder().cache(cache)
            .retryOnConnectionFailure(true)
            .addInterceptor(mCommonParamsProcessInterceptor)
            .connectTimeout(5 * 60, TimeUnit.SECONDS)
            .readTimeout(5 * 60, TimeUnit.SECONDS)
            .writeTimeout(5 * 60, TimeUnit.SECONDS)

        if (BuildConfig.DEBUG) {
            //测试地址 打印log
            builder.addInterceptor(sLoggingInterceptor)
        } else {
            //正式地址 添加证书
//            builder.sslSocketFactory(getSSLSocketFactory(), HexinX509TrustManager())
        }

        return builder.build()
    }

    /**
     * 请求包装、缓存处理
     * 添加请求Header或cache
     */
    private val mCommonParamsProcessInterceptor = Interceptor { chain ->
        val original = chain.request()

        //请求定制(添加请求头)
        val requestBuilder = original.newBuilder().apply {
            addHeader("Accept", "application/json")
            addHeader("Content-Type", "application/json")
            addHeader("version", HxdGlobalInfo.versionCode)
            //设备型号
            addHeader("deviceVersion", MobileInfoManager.getSystemModel())
            //设备分辨率
            addHeader(
                "resolutionRatio",
                "${HxdGlobalInfo.deviceHeight}*${HxdGlobalInfo.deviceWidth}"
            )
            addHeader("channel", Channel_Number)
            addHeader(
                "mobileModel",
                DeviceInfoUtil.getDeviceBrand() + " " + DeviceInfoUtil.getSystemModel()
            )
            addHeader("sysVersion", DeviceInfoUtil.getSystemVersion())
            addHeader("os", "Android")
            addHeader("device", HxdGlobalInfo.deviceUUID)
            addHeader("Authorization", token ?: "")
        }

        val request = requestBuilder.build()
        chain.proceed(request)
    }

    /**
     * 打印返回的json数据拦截器
     */
    private val sLoggingInterceptor = Interceptor { chain ->
        val request = chain.request()
        val response = chain.proceed(request)
        val bodyString = response.body()?.string() ?: ""

        // 解决响应时崩溃无log问题
        val sbRequest = StringBuffer()
        bodyToString(request, sbRequest)

        Log.d(
            "OkHttp",
            "\n请求地址:${request?.url()?.toString()}\n请求方式:${request.method()}\n\n$sbRequest\n返回参数:\n$bodyString\n"
        )

        response.newBuilder().body(ResponseBody.create(response.body()!!.contentType(), bodyString))
            .build()
    }

    private fun bodyToString(request: Request, sb: StringBuffer): String {
        try {
            sb.append("请求头的参数：\n")
            request.headers().toMultimap().forEach {
                sb.append(it.key)
                sb.append("=")
                sb.append(it.value)
                sb.append("\n")
            }
            sb.append("\n接口的入参数据：\n")
            if (request.method() == "POST") {
                if (request.body() is FormBody) {
                    val body = request.body() as FormBody
                    if (body.size() == 0) {
                        sb.append("无入参数据\n")
                    } else
                        for (index in 0 until body.size()) {
                            sb.append(body.name(index) + "=" + body.value(index) + ";\n")
                        }
                } else
                    sb.append("无入参数据\n")
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return sb.toString()
    }

    @Throws(NoSuchAlgorithmException::class, KeyManagementException::class)
    private fun getSSLSocketFactory(): SSLSocketFactory {
        val context = SSLContext.getInstance("TLS")
        val trustManagers = arrayOf<TrustManager>(HexinX509TrustManager())
        context.init(null, trustManagers, SecureRandom())
        return context.socketFactory
    }

}